package com.totem.base.util;

import com.totem.admin.vo.FileUrlVO;
import com.totem.base.constants.CommonConstants;
import com.totem.base.constants.ErrorCode;
import com.totem.base.enums.FileTypeEnum;
import com.totem.base.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class S3Util {

    public static FileUrlVO uploadFile(S3Client s3Client, MultipartFile file, String fileType) {
        String originalFilename = file.getOriginalFilename();
        String newFilename = DateUtils.getCurrentTimestampStr()+"_"+originalFilename;
        long size = file.getSize();
        String s3Path = null;
        if(FileTypeEnum.COVER.getCode().equalsIgnoreCase(fileType)){
            s3Path = CommonConstants.FILE_COVER_PREFIX + newFilename;
        }
        if(FileTypeEnum.CAROUSEL.getCode().equalsIgnoreCase(fileType)){
            s3Path = CommonConstants.FILE_CAROUSEL_PREFIX + newFilename;
        }
        if(FileTypeEnum.VIDEO.getCode().equalsIgnoreCase(fileType)){
            s3Path = CommonConstants.FILE_VIDEO_PREFIX + newFilename;
        }
        FileUrlVO urlVO = new FileUrlVO();
        try {
            ListBucketsResponse response = s3Client.listBuckets();
            List<Bucket> bucketList = response.buckets();
            if(CollectionUtils.isEmpty(bucketList)){
                throw new BaseException(ErrorCode.CLOUD_S3_ERROR);
            }
            InputStream is = file.getInputStream();
            String name = bucketList.get(0).name();
            putS3Object(s3Client, name, s3Path, is, size);
            String s3Url = getUrl(s3Client, name, s3Path);
            String httpUrl = s3Url.replace("https", "http");
            urlVO.setFileHttpsUrl(s3Url);
            urlVO.setFileUrl(httpUrl);
        } catch (S3Exception | IOException e) {
            log.error("上传文件失败", e);
        }
        return urlVO;
    }

    public static void putS3Object(S3Client s3, String bucketName, String objectKey, InputStream is, long size) {
        try {
            Map<String, String> metadata = new HashMap<>();
            //metadata.put("x-amz-meta-myVal", "test");
            PutObjectRequest putOb = PutObjectRequest.builder()
                    .bucket(bucketName)
                    .key(objectKey)
                    //        .metadata(metadata)
                    .build();

            s3.putObject(putOb, RequestBody.fromInputStream(is, size));
            log.info("Successfully placed {} into bucket {}", objectKey, bucketName);
        } catch (S3Exception e) {
            log.error("上传文件失败", e);
            throw new BaseException(ErrorCode.FILE_UPLOAD_ERROR);
        }
    }

    public static String getUrl(S3Client s3, String bucketName, String objectKey){
        return s3.utilities().getUrl( GetUrlRequest.builder()
                        .bucket(bucketName)
                        .key(objectKey)
                        .build())
                .toExternalForm();
    }
}
